/*
 * Pattern.java
 *
 * Created on 27 Март 2008 г., 1:32
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package trim.common.result;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import trim.common.inputdata.FormatOrder;
import trim.common.Format;
import trim.common.Material;

/**
 * Класс представляющий собой отдельный способ раскроя и его интенсивность
 * использования.
 *
 * @author Дмитрий
 */
public class Pattern extends ArrayList<PatternItem>
{
  //Ширина тамбура для данного способа раскроя
  private Material material;
  //количество применений способа раскроя
  private int count=0;

  /**
   * Добавление рулона в конец способа раскроя.
   * @param count количество вставляемых элементов
   * @param pi добавляемый элемент
   */
  public void add(PatternItem pi,int count)
  {
    for(int i=0;i<count;i++)
      add(pi);
  }

  /**
   * Добавление формата в конец способа раскроя
   * @param rf добавляемый формат
   * @param count количество
   */
  public void add(Format rf,int count)
  {
    for(int i=0;i<count;i++)
      add(new PatternItem(rf));
  }

  /**
   * Добавление рулона в способ раскроя.
   * @param index номер позиции для вставки
   * @param pi добавляемый элемент
   * @param count количество вставляемых элементов
   */
  public void add(int index,PatternItem pi,int count)
  {
    for(int i=0;i<count;i++)
      add(index,pi);
  }

  /**
   * Получение способа раскроя сгруппированого по форматам
   * @return способ раскроя в виде пар <формат,количество>
   */
  public List<TrimmedFormatOrder> getTrimmedFormatOrders()
  {
    Map<Object,TrimmedFormatOrder> m=new HashMap();
    for(PatternItem pi:this)
    {
      TrimmedFormatOrder rp=m.get(pi.getFormat().getLength());
      if(rp==null)
      {
        rp=new TrimmedFormatOrder();
        rp.setFormat(pi.getFormat());
        m.put(rp.getFormat().getLength(),rp);
      }
      rp.setCount(rp.getCount()+1);
    }
    return new ArrayList(m.values());
  }

  /**
   * Интенсивность способа раскроя
   * @return интенсивность способа раскроя
   */
  public int getCount()
  {
    return count;
  }

  /**
   * Интенсивность способа раскроя
   * @param patternNumber интенсивность способа раскроя
   */
  public void setCount(int patternNumber)
  {
    this.count = patternNumber;
  }

  /**
   * Получение количества различных форматов в раскрое
   * @return количество различных форматов в раскрое
   */
  public int getFormatCount()
  {
    return getTrimmedFormatOrders().size();
  }

  /**
   * Размер заготовки для данного раскроя.
   * @return ширина заготовки
   */
  public Material getMaterial()
  {
    return material;
  }
  /**
   * Размер заготовки для данного раскроя.
   * @param sourceMaterial Исходный материал
   */
  public void setMaterial(Material sourceMaterial)
  {
    this.material = sourceMaterial;
  }

  /**
   * Отход способа раскроя (без учета его интенсивности использования)
   * @return размер отхода раскроя
   */
  public int getPatternTail()
  {
    int res=material.getLength();
    for(int i=0;i<size();i++)
      res-=get(i).getFormat().getLength();//*items.get(i).getCount();
    return res;
  }

  /**
   * Полезная площадь способа раскроя
   * @return использованная площадь раскроя
   */
  public int getPatternUsedArea()
  {
    int res=0;
    for(int i=0;i<size();i++)
      res+=get(i).getFormat().getLength();//*items.get(i).getCount();
    return res;
  }

  /**
   * Расчет коэффициента эффективности для данного способа раскроя.
   * Равен отношению полезной площади к общей площади тамбура.
   * @return эффективность способа раскроя. Величина в диапазоне [0,1].
   */
  public double getPatternEfficiency()
  {
    return (double)getPatternUsedArea()/(double)getMaterial().getLength();
  }

}
